﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace Nature
{
    public interface IIdealGasSpeciesMolecularTransportProperties
    {
        int Nsp { get; }

        void CalcSpeciesIdealGasViscosities(double temperature, double[] viscosities);

        void CalcSpeciesIdealGasThermalConductivities(double temperature, double[] conductivities);

        void CalcSpeciesIdealGasSelfDiffusivities(double temperature, double pressure, double[] selfDiffusivities);

        void CalcSpeciesIdealGasDiffusivities(double temperature, double pressure, double[][] diffusivities);

        void CalcSpeciesIdealGasThermoDiffusivities(double temperature, double[][] thermDiffusivities);
    }

    public interface IIdealGasMixtureMolecularTransportProperties
    {
        double CalcMixtureIdealGasViscosity(IdealGasMixture mixture);

        double CalcMixtureIdealGasDiffusivity(IdealGasMixture mixture);

        double CalcMixtureIdealGasThermalConductivity(IdealGasMixture mixture);
    }

    public sealed class LogTApproximationIdealGasSpeciesMolecularTransportProperties : IIdealGasSpeciesMolecularTransportProperties
    {
        #region IIdealGasSpeciesMolecularTransportProperties Members

        public int Nsp
        {
            get { throw new NotImplementedException(); }
        }

        public void CalcSpeciesIdealGasViscosities(double temperature, double[] viscosities)
        {
            throw new NotImplementedException();
        }

        public void CalcSpeciesIdealGasThermalConductivities(double temperature, double[] conductivities)
        {
            throw new NotImplementedException();
        }

        public void CalcSpeciesIdealGasSelfDiffusivities(double temperature, double pressure, double[] selfDiffusivities)
        {
            throw new NotImplementedException();
        }

        public void CalcSpeciesIdealGasDiffusivities(double temperature, double pressure, double[][] diffusivities)
        {
            throw new NotImplementedException();
        }

        public void CalcSpeciesIdealGasThermoDiffusivities(double temperature, double[][] thermDiffusivities)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public abstract class IdealGasMixtureMolecularTransportProperties : IIdealGasMixtureMolecularTransportProperties
    {
        #region Static Methods

        public static double WilkeMixtureIdealGasViscosity(IdealGasMixture mixture)
        {
            int nsp = mixture.Nsp;
            double vsum = 0.0;
            var v = mixture.SpeciesViscosities.Data;
            var w = mixture.Model.SpeciesMolarMasses.Data;
            var x = mixture.SpeciesMoleFractions;
            var wilke = mixture.SpeciesWilkeMatrix;
            for (int isp = 0; isp < nsp; ++isp)
            {
                double del = 0.0;
                var f = wilke[isp];
                for (int jsp = 0; jsp < nsp; ++jsp) { del += x[jsp] * f[jsp]; }
                vsum += x[isp] * v[isp] / del;
            }
            return vsum;
        }

        public static double WilkeMixtureIdealGasThermalConductivity(IdealGasMixture mixture)
        {
            int nsp = mixture.Nsp;
            double lamSum = 0.0;
            var lam = mixture.SpeciesThermalConductivities;
            var w = mixture.Model.SpeciesMolarMasses;
            var x = mixture.SpeciesMoleFractions;
            var wilke = mixture.SpeciesWilkeMatrix;
            for (int isp = 0; isp < nsp; ++isp)
            {
                double del = 0.0;
                var f = wilke[isp];
                for (int jsp = 0; jsp < nsp; ++jsp) { del += x[jsp] * f[jsp]; }
                lamSum += x[isp] * lam[isp] / del;
            }
            return lamSum;
        }
        #endregion

        #region IIgMxMolecularTransportProperties Members

        public abstract double CalcMixtureIdealGasViscosity(IdealGasMixture mixture);

        public abstract double CalcMixtureIdealGasDiffusivity(IdealGasMixture mixture);

        public abstract double CalcMixtureIdealGasThermalConductivity(IdealGasMixture mixture);

        #endregion
    }

    public class WilkeIdealGasMixtureMolecularTransportProperties : IdealGasMixtureMolecularTransportProperties
    {
        public override double CalcMixtureIdealGasViscosity(IdealGasMixture mixture)
        {
            return IdealGasMixtureMolecularTransportProperties.WilkeMixtureIdealGasViscosity(mixture);
        }

        public override double CalcMixtureIdealGasDiffusivity(IdealGasMixture mixture)
        {
            double la = mixture.ThermalConductivity;
            double cv = mixture.MolarCv;
            double cmix = mixture.MolarDensity;
            return la / cmix / cv;
        }

        public override double CalcMixtureIdealGasThermalConductivity(IdealGasMixture mixture)
        {
            return IdealGasMixtureMolecularTransportProperties.WilkeMixtureIdealGasThermalConductivity(mixture);
        }
    }

}
